﻿
namespace Patterns4Net.PatternEnforcer.Cmd
{
    using System;
    using System.Linq;
    using System.Text;
    using Patterns4Net.Core;
    using Output;
    using Core;
    using Core.Config;
    using System.Collections.Generic;

    /// <summary>
    /// Implements Pattern Enforcer command line interface.
    /// </summary>
    public static class Program
    {
        /// <summary>
        /// The main entry to Pattern Enforcer command line program.
        /// </summary>
        public static void Main(string[] args)
        {
            var arguments = new List<string>();
            var errors = new List<string>();
            var options = ArgumentsParser.Parse<Options>(args, arguments, errors);
            IOutputFormatter outputFormatter;

            if (errors.Count > 0)
            {
                Console.Write(string.Join("\n", errors));
                return;
            }

            if (options.Help || args.Count() == 0)
            {
                Console.WriteLine("Pattern Enforcer is part of the Pattern4Net project.");
                Console.WriteLine(
                    "usage: pattern-enforcer.exe [-config-file filename] [-output-format format-id] assembly1 assembly2 ...");
                Console.WriteLine("Supported output formats: plain-text (default), Visual Studio (id: vs), " + 
					"Visual Studio (shows errors as warnings, id:vs-warnings), xml (id: xml)");
                return;
            }

            if (string.IsNullOrWhiteSpace(options.OutputFormat))
            {
                outputFormatter = new CommandLineOutputFormatter();
            }		
            else if (string.CompareOrdinal(options.OutputFormat, "vs") == 0)
            {
                outputFormatter = new VisualStudioOutput();
            }
            else if (string.CompareOrdinal(options.OutputFormat, "xml") == 0)
            {
                outputFormatter = new XmlOutput();
            }
			else if (string.CompareOrdinal(options.OutputFormat, "vs-warnings") == 0)
			{
				outputFormatter = new VisualStudioOutput(true);
			}
            else
            {
                Console.WriteLine("Warning: output format with id {0} does not exist. ");
                Console.WriteLine("Type 'pattern-enforcer -help' for list of supported out formats. ");
                outputFormatter = new CommandLineOutputFormatter();
            }

            var errorsOutput = new StringBuilder();
            var config = Config.Create(options.ConfigFile, errorsOutput);
            var container = CompositionContainerHelper.GetContainer(config, errorsOutput);
            var patternEnforcer = CompositionContainerHelper.GetPatternEnforcer(container, errorsOutput);
            if (errorsOutput.Length > 0)
            {
                Console.WriteLine(errorsOutput);
                Console.WriteLine();
            }

            if (patternEnforcer == null)
            {
                return;
            }

            outputFormatter.Start(Console.Out);
            foreach (var assemblyFilename in arguments)
            {
                try
                {
                    var result = patternEnforcer.CheckAssembly(assemblyFilename);
                    outputFormatter.Print(result, Console.Out);
                }
                catch (PatternEnforcerException ex)
                {
                    Console.WriteLine("An error occurred: " + ex.Message);
                }
            }

            outputFormatter.End(Console.Out);

#if DEBUG
            Console.WriteLine();
            Console.WriteLine("PRESS ANY KEY...");
            Console.ReadLine();
#endif
        }
    }
}
